
#include "Common.hpp"
#include <fstream>
#include <unistd.h>
#include <sys/wait.h>

#include "Thread.hpp"
#include <vector>
const int default_listen_sockfd = -1;
const int default_connect_sockfd = -1;
uint16_t default_port = 8080;
int backlog = 6;
class TcpServer : public NoCopy
{
public:
    TcpServer(int listen_sockfd = default_listen_sockfd, int port = default_port)
        : _listen_sockfd(listen_sockfd), _connect_sockfd(default_connect_sockfd), _port(port), _isrunning(false)
    {
    }
    void Init()
    {
        _listen_sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (_listen_sockfd < 0)
        {
            LOG(LogLevel::FATAL) << "socket erro";
            exit(SOCKET_ERRO);
        }
        LOG(LogLevel::INFORMATION) << "socket success!";

        INETADDR server(_port);
        int n = bind(_listen_sockfd, server.NetAddrPtr(), server.NetAddrLen());
        if (n == -1)
        {
            LOG(LogLevel::FATAL) << "bind erro";
            exit(BIND_ERRO);
        }
        LOG(LogLevel::INFORMATION) << "bind success!";

        int m = listen(_listen_sockfd, backlog);
        if (m == -1)
        {
            LOG(LogLevel::FATAL) << "listen erro";
            exit(LISTEN_ERRO);
        }
        LOG(LogLevel::INFORMATION) << "listen success!";
    }
    void Handle_Client_Request(int sockfd, INETADDR &addr)
    {
        while (1)
        {
            char rbuf[1024] = {0};
            ssize_t r = read(sockfd, rbuf, sizeof(rbuf) - 1);
            if (r > 0)
            {
                rbuf[r] = '\0';
                string message = rbuf;
                LOG(LogLevel::INFORMATION) << addr.StringAddr() << " # " << message;
            }
            else if (r == 0)
            {
                LOG(LogLevel::INFORMATION) << "client exit!";
                close(sockfd);
                break;
            }
            else
            {
                LOG(LogLevel::INFORMATION) << "read erro!";
                close(sockfd);

                break;
            }
            string wstr = "你好,客户端";
            wstr.append(rbuf);
            ssize_t w = write(sockfd, wstr.c_str(), wstr.size());
            if (w == -1)
            {
                LOG(LogLevel::INFORMATION) << "write erro";
                close(sockfd);

                break;
            }
        }
    }
    void Run()
    {
        _isrunning = true;
        while (_isrunning)
        {
            struct sockaddr_in client;
            socklen_t len = sizeof(client);
            _connect_sockfd = accept(_listen_sockfd, CONVERT(client), &len);
            if (_connect_sockfd == -1)
            {
                LOG(LogLevel::WARNING) << "accept erro";
                continue;
            }
            INETADDR peer(client);
            LOG(LogLevel::INFORMATION) << "accept success,peer adderss: " << peer.StringAddr();
            Thread thread([this, &peer](){
                Handle_Client_Request(_connect_sockfd, peer);
            });
            thread.Start();
            thread.Detach();
        }
        _isrunning = false;
    }  
    ~TcpServer()
    {
        close(_listen_sockfd);
        close(_connect_sockfd);
    }

private:
    int _listen_sockfd;
    int _connect_sockfd;
    uint16_t _port;
    bool _isrunning;
};